/**
 * 北京中流科技有限公司 版权所有
 * http://www.chinasoa.com.cn
 */
package cn.com.chinasoa.cms.portlet.action;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.portlet.PortletException;
import javax.portlet.PortletRequest;

import org.jaxen.JaxenException;
import org.jaxen.XPath;
import org.jaxen.dom.DOMXPath;
import org.w3c.dom.Element;

import cn.com.chinasoa.cms.portlet.render.ContentRenderFilter;

import com.x4ee.soa.portal.framework.core.FrameworkConfig;
import com.x4ee.soa.portal.framework.tools.ConfigUtils;

/**
 * @author 刘洋(liuyang@chinasoa.com.cn)
 * 2007-8-6下午02:02:57
 */
public class FrameworkConfigWraper {

	public static final String FRAMEWORK_URN_PROPERTIES_FILE="frameworkUrn.properties";

	public static final String FRAMEWORK_URN_PROPERTIES="frameworkUrnProperties";
	public static final String FRAMEWORK_URN_MAP="frameworkUrnMap";
	public static final String FRAMEWORK_URI_MAP="frameworkUriMap";
	public static final String FRAMEWORK_OUTLET_MAP="frameworkOutletMap";
	
	public static final String FRAMEWORK_URN_URN="frameworkUrn";

	public static final String DEFAULT="default";
	public static final String SUCCESS="success";
	public static final String ERROR="error";
	
	public static final String OUTLET="outlet";
	public static final String URI="uri";
	
	public static final String URI_TABLE="URITable";
	public static final String URI_CREATE_ERROR="URICreateError";
	public static final String UPLOAD="upload";
	public static final String OUTLET_TABLE="OutletTable";
	public static final String OUTLET_CREATE_ERROR="OutletCreateError";
	
	private Element xmlConfig = null;
	private FrameworkConfig frameworkConfig = null;

	public FrameworkConfigWraper(Element tXmlConfig, FrameworkConfig tFrameworkConfig){
		frameworkConfig = tFrameworkConfig;
		xmlConfig = tXmlConfig;
	}

	public FrameworkConfig getFrameworkConfig() {
		return frameworkConfig;
	}

	public Element getXmlConfig() {
		return xmlConfig;
	}

	/**
	 * @param key
	 * @param value
	 * @return
	 */
	public boolean addOutlet(String key,String value){
		boolean result = false;
		Element root = this.getXmlConfig().getOwnerDocument().getDocumentElement();
		Element render = FrameworkConfigWraper.getRenderByName(root,"ViewIndex");
		Element filter = FrameworkConfigWraper.getFilter(render);

		if(filter!=null){
			Element outletElement = FrameworkConfigWraper.getOutlet(render,key);
			if(outletElement!=null){
				String tValue = outletElement.getAttribute("value");
				if((tValue!=null)&&(tValue.equals(value))){
					return result;
				}else{
					outletElement.setAttribute("value",value);
					result = true;
				}
			}else{
				String filterName = filter.getAttribute("name");
				outletElement = render.getOwnerDocument().createElement(FrameworkConfigWraper.OUTLET);
				outletElement.setAttribute("filter",filterName);
				outletElement.setAttribute("key",key);
				outletElement.setAttribute("value",value);
				render.appendChild(outletElement);
			}
			try {
				this.getFrameworkConfig().save(this.getFrameworkConfig().getPortletConfig());
				this.getFrameworkConfig().load(this.getFrameworkConfig().getPortletConfig());
				result = true;
				return result;
			} catch (PortletException e) {
				e.printStackTrace();
				result = false;
				return result;
			}
		}else{
			return result;
		}
	}

	/**
	 * @param key
	 * @return
	 */
	public boolean removeOutlet(String key){
		boolean result = false;
		Element root = this.getXmlConfig().getOwnerDocument().getDocumentElement();
		Element render = FrameworkConfigWraper.getRenderByName(root,"ViewIndex");
		Element filter = FrameworkConfigWraper.getFilter(render);

		if(filter!=null){
			Element outletElement = FrameworkConfigWraper.getOutlet(render,key);
			if(outletElement!=null){
				outletElement.getParentNode().removeChild(outletElement);
				try {
					this.getFrameworkConfig().save(this.getFrameworkConfig().getPortletConfig());
					this.getFrameworkConfig().load(this.getFrameworkConfig().getPortletConfig());
					return true;
				} catch (PortletException e) {
					e.printStackTrace();
					return false;
				}
			}else{
				return result;
			}
		}else{
			return result;
		}
	}

	/**
	 * @param key
	 * @param path
	 * @return
	 */
	public boolean addUri(String key,String path){
		boolean result = false;
		Element root = this.getXmlConfig().getOwnerDocument().getDocumentElement();
		Element render = FrameworkConfigWraper.getRenderByName(root,"ViewIndex");
		Element filter = FrameworkConfigWraper.getFilter(render);

		if(filter!=null){
			Element uriElement = FrameworkConfigWraper.getUri(render,key);
			if(uriElement!=null){
				String tPath = uriElement.getAttribute("path");
				if((tPath!=null)&&(tPath.equals(path))){
					return result;
				}else{
					uriElement.setAttribute("path",path);
					result = true;
				}
			}else{
				uriElement = render.getOwnerDocument().createElement(FrameworkConfigWraper.URI);
				uriElement.setAttribute("name",key);
				uriElement.setAttribute("path",path);
				render.appendChild(uriElement);
			}
			try {
				this.getFrameworkConfig().save(this.getFrameworkConfig().getPortletConfig());
				this.getFrameworkConfig().load(this.getFrameworkConfig().getPortletConfig());
				result = true;
				return result;
			} catch (PortletException e) {
				e.printStackTrace();
				result = false;
				return result;
			}
		}else{
			return result;
		}
	}	

	/**
	 * @param key
	 * @return
	 */
	public boolean removeUri(String key){
		boolean result = false;
		Element root = this.getXmlConfig().getOwnerDocument().getDocumentElement();
		Element render = FrameworkConfigWraper.getRenderByName(root,"ViewIndex");
		Element filter = FrameworkConfigWraper.getFilter(render);

		if(filter!=null){
			Element uriElement = FrameworkConfigWraper.getUri(render,key);
			if(uriElement!=null){
				uriElement.getParentNode().removeChild(uriElement);
				try {
					XPath xpath = new DOMXPath("outlet[@value='"+key+"']");
					List xpmList = xpath.selectNodes(render);
					if(xpmList.isEmpty()){
						
					}else{
						for(Iterator xpmIt = xpmList.iterator();xpmIt.hasNext();){
							Element outletElement = (Element)xpmIt.next();
							outletElement.getParentNode().removeChild(outletElement);
						}
					}
				} catch (JaxenException e) {
					e.printStackTrace();
				}
				try {
					this.getFrameworkConfig().save(this.getFrameworkConfig().getPortletConfig());
					this.getFrameworkConfig().load(this.getFrameworkConfig().getPortletConfig());
					result = true;
					return result;
				} catch (PortletException e) {
					e.printStackTrace();
					result = false;
					return result;
				}
			}else{
				return result;
			}
		}else{
			return result;
		}
	}

	/**
	 * @param root
	 * @param viewIndex
	 * @return
	 */
	public static Element getRenderByName(Element root,String viewIndex){
		if(root==null)return null;
		try {
			XPath xpath = new DOMXPath("//render[@name='"+viewIndex+"']");
			List xpmList = xpath.selectNodes(root);
			if(xpmList.isEmpty()){
				return null;
			}else{
				return (Element)xpmList.iterator().next();
			}
		} catch (JaxenException e) {
			e.printStackTrace();
			return null;
		}
	}
	/**
	 * @param root
	 * @param viewIndex
	 * @return
	 */
	public static Map getURIMapByRenderName(Element root,String viewIndex){
		Map frameworkUriMap = new HashMap();
		if(root==null)return frameworkUriMap;
		try {
			XPath xpath = new DOMXPath("//render[@name='"+viewIndex+"']");
			List xpmList = xpath.selectNodes(root);
			if(xpmList.isEmpty()){
				return frameworkUriMap;
			}else{
				Element renderElement = (Element)(xpmList.iterator().next());
				XPath uriXPath = new DOMXPath("uri");
				List uriList = uriXPath.selectNodes(renderElement);
				for(Iterator uriIT = uriList.iterator();uriIT.hasNext();){
					Element uriElement = (Element)(uriIT.next());
					String name = uriElement.getAttribute("name");
					String path = uriElement.getAttribute("path");
					frameworkUriMap.put(name, path);
				}
				return frameworkUriMap;
			}
		} catch (JaxenException e) {
			e.printStackTrace();
			return frameworkUriMap;
		}
	}
	/**
	 * @param root
	 * @param viewIndex
	 * @return
	 */
	public static Element getOutlet(String outletKey,Element root,String viewIndex){
		Element renderElement = FrameworkConfigWraper.getRenderByName(root,viewIndex);
		if(renderElement!=null){
			return FrameworkConfigWraper.getOutlet(renderElement,outletKey);
		}else{
			return null;
		}
	}

	/**
	 * @param root
	 * @param viewIndex
	 * @return
	 */
	public static boolean hasOutlet(String outletKey,Element root,String viewIndex){
		Element outletElement = FrameworkConfigWraper.getOutlet(outletKey,root,viewIndex);
		if(outletElement==null){
			return false;
		}else{
			return true; 
		}
	}	
	/**
	 * @param render
	 * @return
	 */
	public static Element getFilter(Element render){
		if(render==null)return null;
		try {
			XPath xpath = new DOMXPath("filter[@class='"+ContentRenderFilter.class.getName()+"']");
			List xpmList = xpath.selectNodes(render);
			if(xpmList.isEmpty()){
				return null;
			}else{
				return (Element)xpmList.iterator().next();
			}
		} catch (JaxenException e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * @param render
	 * @param outletKey
	 * @return
	 */
	public static Element getOutlet(Element render,String outletKey){
		if(render==null)return null;
		try {
			XPath xpath = new DOMXPath("outlet[@key='"+outletKey+"']");
			List xpmList = xpath.selectNodes(render);
			if(xpmList.isEmpty()){
				return null;
			}else{
				return (Element)xpmList.iterator().next();
			}
		} catch (JaxenException e) {
			e.printStackTrace();
			return null;
		}
	}
	/**
	 * @param root
	 * @param viewIndex
	 * @return
	 */
	public static Map getOutletMapByRenderName(Element root,String viewIndex){
		Map frameworkOutletMap = new HashMap();
		if(root==null)return frameworkOutletMap;
		try {
			XPath xpath = new DOMXPath("//render[@name='"+viewIndex+"']");
			List xpmList = xpath.selectNodes(root);
			if(xpmList.isEmpty()){
				return frameworkOutletMap;
			}else{
				Element renderElement = (Element)(xpmList.iterator().next());
				XPath uriXPath = new DOMXPath("outlet[@filter='contentRenderFilter']");
				List uriList = uriXPath.selectNodes(renderElement);
				for(Iterator uriIT = uriList.iterator();uriIT.hasNext();){
					Element uriElement = (Element)(uriIT.next());
					String key = uriElement.getAttribute("key");
					String value = uriElement.getAttribute("value");
					frameworkOutletMap.put(key, value);
				}
				return frameworkOutletMap;
			}
		} catch (JaxenException e) {
			e.printStackTrace();
			return frameworkOutletMap;
		}
	}
	/**
	 * @param render
	 * @param uriKey
	 * @return
	 */
	public static Element getUri(Element render,String uriKey){
		if(render==null)return null;
		try {
			XPath xpath = new DOMXPath("uri[@name='"+uriKey+"']");
			List xpmList = xpath.selectNodes(render);
			if(xpmList.isEmpty()){
				return null;
			}else{
				return (Element)xpmList.iterator().next();
			}
		} catch (JaxenException e) {
			e.printStackTrace();
			return null;
		}
	}

	public static File getPortletTargetDir(PortletRequest tPortletRequest,String dirName){
		String portletAppPath = ConfigUtils.getPortletConfig(tPortletRequest).getPortletContext().getRealPath("");
		File portletAppDir = new File(portletAppPath);
		if((portletAppDir!=null)&&(portletAppDir.exists())&&(portletAppDir.isDirectory())){
			File portletsDir = new File(portletAppDir,"portlets");
			if((portletsDir!=null)&&(portletsDir.exists())&&(portletsDir.isDirectory())){
				File portletDir = new File(portletsDir,ConfigUtils.getPortletConfig(tPortletRequest).getPortletName());
				if((portletDir!=null)&&(portletDir.exists())&&(portletDir.isDirectory())){
					File targetDir = new File(portletDir,dirName);
					List jspList = new ArrayList();
					File[] jspFiles = targetDir.listFiles();
					for(int i=0;i<jspFiles.length;i++){
						File jspFile = jspFiles[i];
						if(jspFile.getName().endsWith(".jsp")){
							jspList.add(jspFile.getName());
						}
					}
					for(Iterator jspIt = jspList.iterator();jspIt.hasNext();){
						String jspName = (String)jspIt.next();
					}					
					return targetDir;
				}
			}
		}
		return portletAppDir;
	}
	public static File getPortletDir(PortletRequest tPortletRequest){
		String portletAppPath = ConfigUtils.getPortletConfig(tPortletRequest).getPortletContext().getRealPath("");
		File portletAppDir = new File(portletAppPath);
		if((portletAppDir!=null)&&(portletAppDir.exists())&&(portletAppDir.isDirectory())){
			File portletsDir = new File(portletAppDir,"portlets");
			if((portletsDir!=null)&&(portletsDir.exists())&&(portletsDir.isDirectory())){
				File portletDir = new File(portletsDir,ConfigUtils.getPortletConfig(tPortletRequest).getPortletName());
				if((portletDir!=null)&&(portletDir.exists())&&(portletDir.isDirectory())){
					return portletDir;
				}
			}
		}
		
		return portletAppDir;
	}
	public static File getPortletJspDir(PortletRequest tPortletRequest){
		return getPortletTargetDir(tPortletRequest,"jsp");
	}
}
